fn closure_math<F: Fn() ->i32>(op: F) -> i32 {
    op()
}

//closure_math，参数是一个泛型F，并且该泛型受 Fn()->i32 trait的限定，
//代表该函数只允许实现 Fn()->i32 trait的类型作为参数。

fn test_1() {
    let a = 2;
    let b = 3;
    assert_eq!(closure_math(|| a + b), 5);
    assert_eq!(closure_math(|| a * b), 6);
}

//闭包作为函数返回值
fn two_times_impl() -> impl Fn(i32) -> i32 {
    let i = 2;
    move |j| j*i
    //此处不用move，编译器通不过
    //move的作用是将捕获变量i的所有权转移到闭包中，而不是引用捕获，以保证闭包可以安全返回
}

fn test_2(){
    let result = two_times_impl();
    assert_eq!(result(3), 6);
}

fn main(){
	for n in 1..101 {
		if n % 15 == 0 {
			println!("fizzbuzz");
		} else if n %3 == 0 {
			println!("fizz");
		}else if n % 5 == 0 {
			println!("buzz");
		}else {
			println!("{}", n);
		}
	}
}